package com.wex.posture;

import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.concurrent.LinkedBlockingQueue;
import android.os.*;

public class SocketClient extends Thread
{

    private Socket socket = null;
    private String ip;
    private int port;
    private int blockSize;
    private boolean run = false;
    private Handler handler;

    private Event event = null;
    private LinkedBlockingQueue<byte[]> sendData = new LinkedBlockingQueue();
    //private LinkedBlockingQueue<byte[]> recvData = new LinkedBlockingQueue();

    //回调接口
    public interface Event
    {
        //连接状态变化
        public abstract void change(boolean connect);
        //有数据收入
        public abstract void recv(byte[] b);
    }

    public SocketClient(String ip, int port, int blockSize, Event _event)
    {
        this.ip = ip;
        this.port = port;
        this.blockSize = blockSize;
        this.event = _event;
        //回调预置
        handler = new Handler() {
            @Override
            public void handleMessage(Message msg)
            {
                //不接收事件
                if (event == null)
                    return;
                switch(msg.what)
                {
                    case 0:
                        event.change(false);
                        break;
                    case 1:
                        event.change(true);
                        break;
                    case 2:
                        event.recv((byte[])msg.obj);
                        break;
                }
            }
        };
        this.start();
    }

    @Override
    public void run()
    {
        try
        {
            socket = new Socket(ip, port);
            //socket.setKeepAlive(true);
            sendData.clear();
            //recvData.clear();
            run = true;
            Log.d("Posture", "SocketClient.run: start");
            //连接事件
            handler.sendEmptyMessage(1);
            new Thread(new Runnable() {
                    @Override
                    public void run()
                    {
                        try
                        {
                            int length;
                            byte[] recvData = new byte[blockSize];
                            Message msg = new Message();
                            msg.what = 2;
                            InputStream input = socket.getInputStream();
                            do {
                                length = input.read(recvData);
                                if (length > 0)
                                {
                                    //组织数据放松消息
                                    byte[] data = new byte[length];
                                    System.arraycopy(data, 0, recvData, 0, length);
                                    //接收数据事件
                                    msg.obj = data;
                                    handler.sendMessage(msg);
                                }
                            } while (run && socket.isConnected() && length >= 0);
                            input.close();
                        }
                        catch(IOException e)
                        {
                            ;
                        }
                    }
                }).start();
            OutputStream output = socket.getOutputStream();
            // test
            //output.write("Hello".getBytes());
            while (run && socket.isConnected())
            {
                byte[] d = sendData.take();
                if (d != null && socket.isConnected())
                    output.write(d);
            }
            output.close();
            socket.close();
            //断开事件
            handler.sendEmptyMessage(0);
            run = false;
        }
        catch (IOException e)
        {
            Log.d("Posture", "SocketClient.run: IOException");
        }
        catch (Exception e)
        {
            Log.d("Posture", "SocketClient.run: Exception");
        }
        Log.d("Posture", "SocketClient.run: end");
    }

    public void send(byte[] buff)
    {
        if (run)
        {
            sendData.add(buff);
        }
    }

    public void exit()
    {
        run = false;
        sendData.add(new byte[8]);
        try
        {
            this.join(10);
        }
        catch (InterruptedException e)
        {
            Log.d("Posture", "SocketClient.exit: InterruptedException");
        }
    }
}
